Skip to content

fix(workflow): include coverImage in search and list API responses#6280

Open
VuMartin wants to merge 10 commits into
apache:mainfrom
VuMartin:n-plus-one-cover-fetches
Open

fix(workflow): include coverImage in search and list API responses#6280
VuMartin wants to merge 10 commits into
apache:mainfrom
VuMartin:n-plus-one-cover-fetches

Conversation

@VuMartin

@VuMartin VuMartin commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

Include workflow cover image data in the dashboard search response to prevent the frontend from needing additional requests to fetch cover images.

This PR fixes the N+1 query issue where each workflow card was making a separate GET /workflow/{wid}/cover request to fetch its cover image.

Before:

· The frontend loads the workflow list (1 request)
· Each card calls workflowCoverService.getCover() individually (N requests)
· Total: 1 + N requests for N workflows
Screenshot 2026-07-10 at 12 37 25 AM
Screenshot 2026-07-10 at 12 37 41 AM

After:

· /dashboard/search and workflow responses now include the coverImage field in the response
· Each card uses the bundled data directly
· Total: 1 request
Screenshot 2026-07-10 at 1 28 12 AM
image
image

Changes made:

  1. Added coverImage field to DashboardWorkflow case class
  2. Modified baseWorkflowSelect() to left join WORKFLOW_COVER_IMAGE and select max(WORKFLOW_COVER_IMAGE.IMAGE).as("cover_image")
  3. Updated WorkflowSearchQueryBuilder to include coverImage in search results
  4. Updated frontend DashboardEntry and DashboardWorkflow interfaces to include coverImage data and use it directly in card rendering
  5. Replaced per-card getCover() calls with direct coverImage usage in card-item.component.ts

Any related issues, documentation, discussions?

Closes #5920
Follow-up to #5704

How was this PR tested?

Manual Testing:

· Verified coverImage field appears in search responses
· Uploaded a test cover image via API and confirmed it appears in search response

Automated Tests:

· Added a test case to verify workflow cover images are included in search results.

Tested with:

sbt "project WorkflowExecutionService" "testOnly *WorkflowResourceSpec -- -z "include workflow cover image in search results""

Was this PR authored or co-authored using generative AI tooling?

Co-authored with ChatGPT 5.5-mini

@github-actions github-actions Bot added engine frontend Changes related to the frontend GUI labels Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @roshiiiz, @Ma77Ball, @aglinxinyuan
    You can notify them by mentioning @roshiiiz, @Ma77Ball, @aglinxinyuan in a comment.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces dashboard workflow-card network fan-out by including each workflow’s coverImage payload directly in workflow list/search responses, so the frontend can render card previews without per-card GET /workflow/{wid}/cover calls.

Changes:

  • Backend: extend workflow search/list query builders to left-join WORKFLOW_COVER_IMAGE and aggregate/select the cover image into DashboardWorkflow.coverImage.
  • Frontend: extend dashboard workflow typings/entry mapping and switch card rendering to use the bundled coverImage value instead of fetching covers per card.
  • Tests: add a backend test asserting cover images are present in workflow search results.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/src/app/dashboard/type/dashboard-workflow.interface.ts Adds coverImage to the workflow dashboard type.
frontend/src/app/dashboard/type/dashboard-entry.ts Maps backend coverImage onto DashboardEntry.coverImageUrl for card rendering.
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.ts Stops per-card cover fetch; uses bundled cover image for workflow cards.
amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala Adds regression test for cover image inclusion in search results.
amber/src/main/scala/org/apache/texera/web/resource/dashboard/WorkflowSearchQueryBuilder.scala Includes cover image in workflow search query + mapping.
amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala Includes cover image in workflow list query + DashboardWorkflow model.
amber/src/main/scala/org/apache/texera/web/resource/dashboard/UnifiedResourceSchema.scala Extends unified schema to carry workflow cover image field.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frontend/src/app/dashboard/type/dashboard-workflow.interface.ts Outdated
@chenlica

chenlica commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@VuMartin Please include screenshots to show the interface before and after the PR.

@mengw15 Please review this PR.

@chenlica chenlica requested a review from mengw15 July 9, 2026 16:50
@codecov-commenter

codecov-commenter commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.07%. Comparing base (9f9f85b) to head (52c9e5a).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6280      +/-   ##
============================================
+ Coverage     61.05%   61.07%   +0.02%     
+ Complexity     3380     3379       -1     
============================================
  Files          1140     1140              
  Lines         44932    44943      +11     
  Branches       4944     4946       +2     
============================================
+ Hits          27432    27448      +16     
+ Misses        15987    15981       -6     
- Partials       1513     1514       +1     
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø) Carriedforward from 496c693
agent-service 44.59% <ø> (ø) Carriedforward from 496c693
amber 66.62% <100.00%> (+0.05%) ⬆️
computing-unit-managing-service 0.00% <ø> (ø) Carriedforward from 496c693
config-service 52.30% <ø> (ø) Carriedforward from 496c693
file-service 63.97% <ø> (ø) Carriedforward from 496c693
frontend 53.25% <100.00%> (ø)
notebook-migration-service 78.94% <ø> (ø) Carriedforward from 496c693
pyamber 91.18% <ø> (ø) Carriedforward from 496c693
workflow-compiling-service 55.14% <ø> (ø) Carriedforward from 496c693

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 4 better · 🔴 1 worse · ⚪ 10 noise (<±5%) · 0 without baseline

Compared against main 9f9f85b benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 424 0.259 23,464/31,334/31,334 us 🟢 -17.0% / 🔴 +111.8%
🟢 bs=100 sw=10 sl=64 946 0.577 104,257/121,942/121,942 us 🟢 -11.6% / 🔴 +18.2%
bs=1000 sw=10 sl=64 1,090 0.665 918,772/955,345/955,345 us ⚪ within ±5% / 🟢 -6.6%
Baseline details

Latest main 9f9f85b from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 424 tuples/sec 429 tuples/sec 814.14 tuples/sec -1.2% -47.9%
bs=10 sw=10 sl=64 MB/s 0.259 MB/s 0.262 MB/s 0.497 MB/s -1.1% -47.9%
bs=10 sw=10 sl=64 p50 23,464 us 20,680 us 12,120 us +13.5% +93.6%
bs=10 sw=10 sl=64 p95 31,334 us 37,751 us 14,792 us -17.0% +111.8%
bs=10 sw=10 sl=64 p99 31,334 us 37,751 us 18,232 us -17.0% +71.9%
bs=100 sw=10 sl=64 throughput 946 tuples/sec 928 tuples/sec 1,050 tuples/sec +1.9% -9.9%
bs=100 sw=10 sl=64 MB/s 0.577 MB/s 0.567 MB/s 0.641 MB/s +1.8% -10.0%
bs=100 sw=10 sl=64 p50 104,257 us 102,108 us 96,227 us +2.1% +8.3%
bs=100 sw=10 sl=64 p95 121,942 us 137,869 us 103,174 us -11.6% +18.2%
bs=100 sw=10 sl=64 p99 121,942 us 137,869 us 111,033 us -11.6% +9.8%
bs=1000 sw=10 sl=64 throughput 1,090 tuples/sec 1,091 tuples/sec 1,072 tuples/sec -0.1% +1.6%
bs=1000 sw=10 sl=64 MB/s 0.665 MB/s 0.666 MB/s 0.655 MB/s -0.2% +1.6%
bs=1000 sw=10 sl=64 p50 918,772 us 917,398 us 950,645 us +0.1% -3.4%
bs=1000 sw=10 sl=64 p95 955,345 us 944,026 us 991,936 us +1.2% -3.7%
bs=1000 sw=10 sl=64 p99 955,345 us 944,026 us 1,022,498 us +1.2% -6.6%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,471.68,200,128000,424,0.259,23464.15,31334.29,31334.29
1,100,10,64,20,2114.46,2000,1280000,946,0.577,104257.19,121942.23,121942.23
2,1000,10,64,20,18344.08,20000,12800000,1090,0.665,918772.41,955344.73,955344.73

@xuang7 xuang7 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Could you add a test case for the uncovered part?

@xuang7 xuang7 added release/v1.2 back porting to release/v1.2 and removed release/v1.2 back porting to release/v1.2 labels Jul 10, 2026
@VuMartin

Copy link
Copy Markdown
Contributor Author

Thanks, added the requested test coverage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

engine frontend Changes related to the frontend GUI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fold workflow cover into list/search payload to avoid per-card N+1 fetches

5 participants